package warriorCombat;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 * The warrior class defines all required attributes for a given warrior
 * 
 * @author Brett Hoyer
 */
public class Warrior
{
	private String name;
	private int health;
	private String placeOfOrigin;
	private String personalDescription;
	private String filePath;
	private int serial;//serial number will be assigned by server

	/**
	 * Creates a new warrior with 100 health
	 * @param name name of warrior
	 * @param placeOfOrigin	place of origin to be used
	 * @param personalDescription	description to be used
	 */
	public Warrior(String name, String placeOfOrigin, String personalDescription)
	{
		//Set Warrior Attributes
		this.name = name;
		this.health = 100;
		this.placeOfOrigin = placeOfOrigin;
		this.personalDescription = personalDescription;
		this.filePath = System.getProperty("user.dir") + File.separator +name + ".wdat";
		this.serial = -1;
	}

	/**
	 * Loads a warrior from a file
	 */
	public Warrior()
	{
		//Initialize attributes
		this.name = "";
		this.health = 0;
		this.placeOfOrigin = "";
		this.personalDescription = "";
		this.filePath = "";
		this.serial = -1;

		try
		{
			//Open warrior File. Data is stored in file by sections seperated by semi-colons
			JFileChooser chooser = new JFileChooser();
			FileNameExtensionFilter filter = new FileNameExtensionFilter("Warrior Data (wdat)", "wdat");
			chooser.setFileFilter(filter);
			chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
			if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
			{
				BufferedReader inputFile = new BufferedReader(new FileReader(chooser.getSelectedFile().getPath()));

				String str = inputFile.readLine();
				str = str + ";" + chooser.getSelectedFile().getPath();
				fromString(str);

				//Close input file
				inputFile.close();
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * Create a warrior from a single input string with given serial
	 * @param str input string
	 * @param serial serial number assigned to warrior by server
	 */
	public Warrior(String in, int serial)
	{
		fromString(in);
		this.serial = serial;
	}

	/**
	 * returns a string containing the description of the warrior formatted with HTML
	 * @return	description to be returned
	 */
	public String getFormattedPersonalDescription()
	{
		String str = "<HTML>&nbsp&nbsp&nbsp&nbsp ";
		int j = 0;
		for(int i=0; i < personalDescription.length(); i++)
		{
			char currentChar = personalDescription.charAt(i);
			if(j>50 && Character.isWhitespace(currentChar))
			{
				str += "<br>&nbsp&nbsp&nbsp&nbsp ";
				j = 0;
			}
			str += currentChar;
			j++;
		}
		str += "</HTML>";
		return str;
	}

	/**
	 * returns current health of the warrior as a string
	 * @return health of warrior
	 */
	public String getHealth()
	{

		return Integer.toString(health);
	}

	/**
	 * returns the name of the warrior
	 * @return	name to be returned
	 */
	public String getName()
	{
		return this.name;
	}

	/**
	 * returns a string containing the description of the warrior
	 * @return	description to be returned
	 */
	public String getPersonalDescription()
	{
		return personalDescription;
	}

	/**
	 * returns a string containing the origin of the warrior
	 * @return	origin to be returned
	 */
	public String getPlaceOfOrigin()
	{
		return this.placeOfOrigin;
	}

	/**
	 * returns serial number of warrior
	 * @return serial number
	 */
	public int getSerial()
	{
		return serial;
	}

	/**
	 * Used by client to get warrior data as an array of objects
	 * @return
	 */
	public Object[] getTableData()
	{
		return new Object[] {name, health, placeOfOrigin, personalDescription, serial};
	}

	/**
	 * increases warrior health by given amount to a maximum of 100
	 * @param hpGained	amount to increase health by
	 * @return updated health of warrior
	 */
	public int gainHealth(int hpGained)
	{
		health += hpGained;
		if(health > 100)
			health = 100;
		return health;
	}

	/**
	 * decreases warrior health by a given amount to a minimum of 0
	 * @param hpLost	amount to decrease health by
	 * @return	updated health of warrior
	 */
	public int loseHealth(int hpLost)
	{
		health -= hpLost;
		if(health < 0)
			health = 0;
		return health;
	}

	/**
	 * Saves a warrior to the current working directory using the wdat extension
	 */
	public void saveWarrior()
	{
		try
		{
			BufferedWriter out = new BufferedWriter(new FileWriter(this.filePath));
			out.write(this.toString());

			out.flush();
			out.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Set instance variables from a given string
	 * @param in String containing instance variable values
	 */
	private void fromString(String in)
	{
		String delim = "[;]+";
		String[] arWar = in.split(delim);
		name = arWar[0];
		health = Integer.parseInt(arWar[1]);
		placeOfOrigin = arWar[2];
		personalDescription = arWar[3];
		filePath = arWar[4];
	}

	/**
	 * returns a representation of a warrior in string form with attributes separated by semicolons,
	 * includes filePath attribute
	 * @return string representation of warrior
	 */
	public String toStringFull()
	{
		String str = "";
		str += name + ";" + health + ";" + placeOfOrigin + ";" 
				+ personalDescription + ";" + filePath + ";" + serial + ";";
		return str;
	}

	/**
	 * overrides method from java object
	 * returns a representation of a warrior in string form with attributes separated by semicolons,
	 * does not include filePath attribute.
	 * @return string representation of warrior
	 */
	public String toString()
	{
		String str = "";
		str += name + ";" + health + ";" + placeOfOrigin + ";" + personalDescription + ";";
		return str;
	}
}